{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "ad5d052db22b9c11",
   "metadata": {},
   "source": [
    "PyTorch 是一个基于 Python 的科学计算库，主要用于深度学习研究。它提供了强大的 GPU 加速张量计算和自动微分功能。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ca6179b00695e19c",
   "metadata": {},
   "source": [
    "## 安装PyTorch\n",
    "访问PyTorch官网获取适合你环境的安装命令：https://pytorch.org/"
   ]
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-13T16:16:57.830668Z",
     "start_time": "2025-07-13T16:16:54.920003Z"
    }
   },
   "cell_type": "code",
   "source": "pip install torch torchvision torchaudio",
   "id": "91137a246ca3b360",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Looking in indexes: https://mirrors.aliyun.com/pypi/simple/Note: you may need to restart the kernel to use updated packages.\n",
      "\n",
      "Requirement already satisfied: torch in d:\\software\\miniconda3\\envs\\mini-gpt\\lib\\site-packages (2.7.1)\n",
      "Requirement already satisfied: torchvision in d:\\software\\miniconda3\\envs\\mini-gpt\\lib\\site-packages (0.22.1)\n",
      "Requirement already satisfied: torchaudio in d:\\software\\miniconda3\\envs\\mini-gpt\\lib\\site-packages (2.7.1)\n",
      "Requirement already satisfied: filelock in d:\\software\\miniconda3\\envs\\mini-gpt\\lib\\site-packages (from torch) (3.18.0)\n",
      "Requirement already satisfied: typing-extensions>=4.10.0 in c:\\users\\lenovo\\appdata\\roaming\\python\\python310\\site-packages (from torch) (4.14.0)\n",
      "Requirement already satisfied: sympy>=1.13.3 in d:\\software\\miniconda3\\envs\\mini-gpt\\lib\\site-packages (from torch) (1.14.0)\n",
      "Requirement already satisfied: networkx in d:\\software\\miniconda3\\envs\\mini-gpt\\lib\\site-packages (from torch) (3.4.2)\n",
      "Requirement already satisfied: jinja2 in c:\\users\\lenovo\\appdata\\roaming\\python\\python310\\site-packages (from torch) (3.1.6)\n",
      "Requirement already satisfied: fsspec in d:\\software\\miniconda3\\envs\\mini-gpt\\lib\\site-packages (from torch) (2025.5.1)\n",
      "Requirement already satisfied: numpy in d:\\software\\miniconda3\\envs\\mini-gpt\\lib\\site-packages (from torchvision) (2.2.6)\n",
      "Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in d:\\software\\miniconda3\\envs\\mini-gpt\\lib\\site-packages (from torchvision) (11.3.0)\n",
      "Requirement already satisfied: mpmath<1.4,>=1.1.0 in d:\\software\\miniconda3\\envs\\mini-gpt\\lib\\site-packages (from sympy>=1.13.3->torch) (1.3.0)\n",
      "Requirement already satisfied: MarkupSafe>=2.0 in c:\\users\\lenovo\\appdata\\roaming\\python\\python310\\site-packages (from jinja2->torch) (3.0.2)\n"
     ]
    }
   ],
   "execution_count": 15
  },
  {
   "cell_type": "markdown",
   "id": "57ca8069a7255cc",
   "metadata": {},
   "source": [
    "## 创建张量"
   ]
  },
  {
   "cell_type": "code",
   "id": "2674a52f2049a17f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-13T14:51:27.219613Z",
     "start_time": "2025-07-13T14:50:58.223129Z"
    }
   },
   "source": [
    "import torch\n",
    "\n",
    "# 从列表创建\n",
    "x = torch.tensor([1, 2, 3])\n",
    "print(x)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([1, 2, 3])\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "cell_type": "code",
   "id": "4ba1eee1b1f258f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-13T14:51:31.268067Z",
     "start_time": "2025-07-13T14:51:30.675431Z"
    }
   },
   "source": [
    "# 特殊张量\n",
    "zeros = torch.zeros(2, 3)  # 2行3列的全0张量\n",
    "ones = torch.ones(2, 3)  # 2行3列的全1张量\n",
    "print(zeros)\n",
    "print(ones)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[0., 0., 0.],\n",
      "        [0., 0., 0.]])\n",
      "tensor([[1., 1., 1.],\n",
      "        [1., 1., 1.]])\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "cell_type": "code",
   "id": "a0ed57a68c18f44d",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-13T14:51:33.573445Z",
     "start_time": "2025-07-13T14:51:33.542203Z"
    }
   },
   "source": [
    "# 类似已有张量\n",
    "z = torch.ones_like(zeros)\n",
    "print(z)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[1., 1., 1.],\n",
      "        [1., 1., 1.]])\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-13T15:40:27.123439Z",
     "start_time": "2025-07-13T15:40:27.108660Z"
    }
   },
   "cell_type": "code",
   "source": [
    "rand = torch.rand(2, 3)  # 2行3列的随机张量(0-1均匀分布)，每个数字处于0-1之间\n",
    "randn = torch.randn(2, 3)  # 2行3列的标准正态分布张量，均值为0，方差为1\n",
    "print(rand)\n",
    "print(randn)"
   ],
   "id": "11b576e48e540372",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[0.2461, 0.8477, 0.6080],\n",
      "        [0.0650, 0.6553, 0.9836]])\n",
      "tensor([[-0.9156, -1.7440,  2.5716],\n",
      "        [ 0.4927, -0.8257, -2.1632]])\n"
     ]
    }
   ],
   "execution_count": 10
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 均值和方差\n",
    "**均值、方差**是统计学中描述数据分布特征的核心指标，以下是它们的定义和解释：\n",
    "\n",
    "---\n",
    "\n",
    "### 1. **均值（Mean）**\n",
    "- **定义**：所有数据的总和除以数据的个数。\n",
    "- **公式**（对于数据集 $x_1, x_2, \\dots, x_n$）：\n",
    "  $\n",
    "  \\text{均值} = \\frac{1}{n} \\sum_{i=1}^n x_i\n",
    "  $\n",
    "- **作用**：反映数据的平均水平。\n",
    "- **示例**：数据集 \\([2, 4, 6]\\) 的均值为 \\((2+4+6)/3 = 4\\)。\n",
    "\n",
    "---\n",
    "\n",
    "### 2. **方差（Variance）**\n",
    "- **定义**：数据与均值之差的平方的平均值，衡量数据的**离散程度**。\n",
    "- **公式**：\n",
    "  $$\n",
    "  \\text{方差} = \\frac{1}{n} \\sum_{i=1}^n (x_i - \\text{均值})^2 \\quad\n",
    "  $$\n",
    "- **作用**：方差越大，数据波动越大；方差越小，数据越集中。\n",
    "- **示例**：数据集 $[2, 4, 6]$ 的方差为 $[(2-4)^2 + (4-4)^2 + (6-4)^2]/3 = \\frac{8}{3} \\approx 2.67$。\n",
    "\n",
    "---"
   ],
   "id": "87492265fb780aa2"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "[2,4,6]\n",
    "[-10,4,18]"
   ],
   "id": "2fddd3fb3d96f8db"
  },
  {
   "cell_type": "code",
   "id": "e31c7ee8d02e75b7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-13T15:38:34.649969Z",
     "start_time": "2025-07-13T15:38:29.138265Z"
    }
   },
   "source": [
    "import torch\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# 创建数据\n",
    "rand = torch.rand(1000)  # 1000个服从[0,1]均匀分布的随机数\n",
    "randn = torch.randn(1000)  # 1000个服从标准正态分布的随机数\n",
    "\n",
    "# 可视化均匀分布，画布大小\n",
    "plt.figure(figsize=(12, 5))\n",
    "\n",
    "# 将画布分为1行2列，当前选择第1列\n",
    "plt.subplot(1, 2, 1)\n",
    "plt.hist(rand.numpy(), bins=50, color='blue')\n",
    "plt.title('Uniform Distribution [0,1]')\n",
    "plt.xlabel('Value')\n",
    "plt.ylabel('Frequency')\n",
    "\n",
    "# 可视化标准正态分布\n",
    "# 将画布分为1行2列，当前选择第2列\n",
    "plt.subplot(1, 2, 2)\n",
    "plt.hist(randn.numpy(), bins=50, color='green')\n",
    "plt.title('Standard Normal Distribution')\n",
    "plt.xlabel('Value')\n",
    "plt.ylabel('Frequency')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 1200x500 with 2 Axes>"
      ],
      "image/png": "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5+JnUVyrWHfVVVdVrovrtNNOOxV69+6dndcwefLkbLs4p2vaZ11lK16P2FdR8Tj/+c9/Kte9+OKLhXbt2hVOOOGEVa7XSSedVG2fn//85ws9e/YsrEmUp7brF+d5nXXWqfU1vXr1Khx99NGF+orfiZrXsjZxzuP3BIDy8sc//jG7Z8QSMcf5559feOCBByrvlVWtv/76td53at6bw8yZM7P7x80331y5rnjfHT58eGHlypWV60ePHp0df+HChdnjiG86duyY3Xurbvetb30re33VMixdurTw8ccfr3Jv7tSpU+Hiiy+uVywR9+1+/fpVHr94XmL72u79q7sHjh8/Pnvds88+W1mWeHzllVdWbn/OOedk6x599NHKde+//35h0KBBhU033bTy/ayuzHEO4rlLL710ldguYr5bb721cv2rr766yr28vuettjinNsWyTp06tc5tdtxxx8IGG2xQ+bhmHHbHHXdkj//85z83KC4pnpMLL7yw1ueqXsvi+4rz9c4771Suf+qpp7L18Zmsen2rfg+oa5+rK1sx5it64YUXssdf/epXq2133nnnZev/9Kc/Va6LY8S6Rx55pHJd/I7EtTr33HPrOFPQtHTfgxYqatGqttaJ7lrF2qe19Yc//CHrUheteoqi/3vUoH3wwQdpxowZ1baPGr26xvqJmpei6KsfLWYiTxS1K0VR+xTN7BtS1pqKrYaipqkucbyoAZo7d26DjxM1Q9G0uj6i3/7Xvva1ysdxneJx1MJFt77mMm/evPTCCy9ktVdVW69FTVl0V4zrXFsrsqricxS1tMUuBWtrdQO/R5PveB4AQtyboqVUtNKJrlvR4iZamkRXsPqOjVT13rxixYrsHrbFFltk9/7aurJFS6uqXZnivhetfqIbYLHFcbSIihZVVberbSKUaC1eHF8p9hHHjrgkYpzajl0zlijet2N9dKGvel4aMv5ntJaKVmDFAa9rE7FAtDiL1jxFUeY4L9EyKFoqra7MdcV8xdguWkpFK+yiWBfPVY351va8NYXY/5pixeKA8fE5aqiqY5yuSQzaH5/1orguu+22W63xWlMq7j+6sVZV7EVRsytnfBaL3zNCfAdoqjge6kNSClqAmv3Ai4NaVlUcPDq6jq2tCMRisPCaA1dGN7zi81UVm1/Xpma5IsiKZET0z6+5viFlrSmSZiH67tclgtzo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7LHHFnr06FFtGubVTTNcfC5+1nxfzzzzTDa9defOnbN9/fjHP17l9W+++WY2NXVc7z59+mTTTT/44IOr7LOustU1VfJDDz1U2GuvvbKphuN8HXbYYYW//vWv9bpeNadIrkuUobapuYt++tOfFrbeeuvss7T55psXrrnmmmpTa4d77rknO9akSZOqrY9zWLzmNZeq52VtP0sAtCz33Xdf4aSTTspini5dumT3jC222KJw1llnZXFJVa+++mph3333ze5tcT8o3oPee++9yvgl9jFixIhs25r3qeL97c9//vMa7+Uff/xxFoP169cvO96wYcMKr7zyyir7jBjt3HPPrdwu7r0zZ87M7kux1DxGbbFE+N3vflfYZpttsnhg2223Ldx+++21xnC1qeseGOele/futcZtEX984QtfyOKKiFM+9alPFe69995az0ttZV7b2K5m7Fnf81ZXnFNTsazFpUOHDoVevXpln5fvf//7hXfffXeV19SMd5577rnCMcccUxg4cGB2HXr37l049NBDs3iuqieeeKIwdOjQ7LNaNd6s65wUn6t6LavG01dddVVhwIAB2TH32Wefwosvvljrd4TNNtssO+ZOO+1UeOCBB2r9fNRVtmLMV9WKFSuyz/igQYOy8xVlGDt27CrfO+r63lDzWkFzqoh/Sp0YA6BliRrsaI0VtblRO9eQsaqiJjBqa994441scNC1FbWYUbMYM+REt4fioPcAAEDrYEwpAGoV3Q2jm8MFF1zQ4LFEvv3tbzcoIVXsyhfHj64eAABA66OlFACriHEaYryqELMfVh2MNi8vvfRSNrZCiHG2YowuAACg9ZCUAgAAACB3uu8BAAAAkDtJKQAAAAByJykFAAAAQO7ap1Zu5cqVae7cualr166poqKi1MUBAMpMcfjNbt26tZlYQvwEADQ2fnr//fdT//79U7t27dpuUioCqpg5CgCgMRYtWpQlptoC8RMA0BTmzJmTNt5447ablIoavuKJaCuBJADQdBYvXtzmEjTiJwCgKeKnYkzRZpNSxSbnEVAJqgCA1uCf//xnuuCCC9J9992XPvzww7TFFlukyZMnp1122aWyyfy4cePSjTfemBYuXJj22muvdMMNN6Qtt9yyXvsXPwEATWFNwwAY6BwAoIy89957WZKpQ4cOWVLqr3/9a7rqqqvSBhtsULnNFVdckX74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/z9kyJAsSbXJJpuk2267La277roN2ueECROy5BYAQJ503wMAKGPRKmqrrbZKb7zxRjbO1PLly9PChQurbROz79U2BlXR2LFjs/GoisucOXNyKDkA0NZJSgEAlLEPPvggvfnmm6lfv35p6NChqUOHDmnatGmVz8+aNSsbc2qPPfaocx+dOnVK3bp1q7YAADQ33fcAAMrIeeedlw477LCsy97cuXPTuHHj0jrrrJOOOeaY1L1793TyySenMWPGpA033DBLLp111llZQsrMewBASyMpBQBQRt55550sAfWf//wn9erVK+29997pySefzP4frrnmmtSuXbs0cuTIbPDyESNGpOuvv77UxQYAWIWkFABAGbn11ltX+3znzp3TxIkTswUAoCUr6ZhSMdPLrrvumrp27Zp69+6djjjiiGzcg6qGDRuWKioqqi2nnXZaycoMAAAAQJknpWbMmJHOOOOMrMn5gw8+mFasWJEOPPDAtGTJkmrbnXLKKWnevHmVyxVXXFGyMgMAAABQ5t337r///mqPp0yZkrWYevbZZ9O+++5buX699dZb7TTGAAAAAJSXkraUqmnRokXZz5gtpqpf/epXaaONNkrbb799Gjt2bPrwww9LVEIAAAAAWtVA5ytXrkznnHNO2muvvbLkU9Gxxx6bTXncv3//9NJLL6ULLrggG3fq9ttvr3U/MctMLEWLFy/OpfwAAAAAlGFSKsaWeuWVV9Jjjz1Wbf2pp55a+f8ddtgh9evXLx1wwAHpzTffTJtvvnmtg6ePHz8+tUQVFWveplBIZa+tvE8AAACgzLvvnXnmmenee+9N06dPTxtvvPFqt91tt92yn2+88Uatz0f3vugGWFzmzJnTLGUGAAAAoExbShUKhXTWWWelO+64Iz388MNp0KBBa3zNCy+8kP2MFlO16dSpU7YAAADQfCrG16OLBEBLTUpFl71bbrkl3XXXXalr165p/vz52fru3bunddddN+uiF88ffPDBqWfPntmYUqNHj85m5hsyZEgpiw4AAABAuSalbrjhhuznsGHDqq2fPHlyOvHEE1PHjh3TQw89lK699tq0ZMmSNGDAgDRy5Mh00UUXlajEAAAAALSK7nurE0moGTNm5FYeAAAAANrQQOcAAAAAtC2SUgAAAADkTlIKAAAAgLY1phQAAAD5qBhfUa/tCuNWP/YvQFPRUgoA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oiK1WPW5usrffMes729XffbXlPtqai25bE2p4X8tW4am/NyW4negFNep3D+zreF3oCn/PrakWKKlx1B5xE/Q1lWMd5OhboVxZR540uYtrmcs0aiBztu3b5+OPPLINHXq1HT55ZenN954I5133nlpwIAB6YQTTkjz5s1rzO4BAFolMRQAQCOTUs8880z6+te/nvr165euvvrqLJh6880304MPPpjmzp2bDj/88KYrKbRx0VqgPgttj88GefE5azpiKACAlNo35EURPE2ePDnNmjUrHXzwwenmm2/OfrZr9//nuAYNGpQ1R990002burwAAGVLDAUA0Mik1A033JCNe3DiiSdmNXy16d27d7rpppsasnsAgFZJDAUA0Mik1Ouvv77GbTp27JhGjRrVkN0DALRKYigAgEaOKRXNzmNgzppi3S9+8YuG7BIAoNUTQwEANDIpNWHChLTRRhvV2tz80ksvbcguAQBaPTEUAEAjk1KzZ8/OBuKsaZNNNsmeAwBgVWIoAIBGJqWiNu+ll15aZf2LL76Yevbs2ZBdAgC0emIoAIBGJqWOOeaY9I1vfCNNnz49ffzxx9nypz/9KZ199tnp6KOPbsguAQBaPTEUAEAjZ9/73ve+l/7+97+nAw44ILVv///vYuXKlemEE04wHgIAQB3EUAAA/6eiUCgUUgO99tprWXPzddddN+2www7ZeAgtzeLFi1P37t3TokWLUrdu3ZrlGBUVqcWqz9VV/uY7Zn1/u1ryNagP77O0/A407Jht4TPbGn5P6nMNmvt3szliiZYeQ+URP0FbVzHeTYa6Fca10MATmjiWaFBLqaKtttoqWwAAqD8xFABAA5NSMf7BlClT0rRp09K7776bNTuvKsZGgKaglQItSUtosQGUNzEUAEAjk1IxGGcEVIccckjafvvtU4XMAQDAGomhAAAamZS69dZb02233ZYOPvjghrwcAKBNEkMBAPyfdqkBOnbsmLbYYouGvBQAoM0SQwEANDIpde6556brrrsuNWLiPgCANkcMBQDQyO57jz32WJo+fXq677770nbbbZc6dOhQ7fnbb7+9IbsFAGjVxFAAAI1MSvXo0SN9/vOfb8hLAQDaLDEUAEAjk1KTJ09uyMsAANo0MRQAQCPHlAofffRReuihh9JPfvKT9P7772fr5s6dmz744IOG7hIAoNUTQwEANKKl1D/+8Y/02c9+Ns2ePTstW7YsfeYzn0ldu3ZNl19+efZ40qRJDdktAECrJoYCAGhkS6mzzz477bLLLum9995L6667buX6GCNh2rRpDdklAECrJ4YCAGhkS6lHH300PfHEE6ljx47V1m+66abpn//8Z0N2CQDQ6omhAAAa2VJq5cqV6eOPP15l/TvvvJM1QQcAYFViKACARraUOvDAA9O1116bfvrTn2aPKyoqssE5x40blw4++OCG7BJapYqK1Ca0lfdZinNWKKSyVorPRls5t5QnMRTkr2J8/W4MhXFuDABlkZS66qqr0ogRI9K2226bli5dmo499tj0+uuvp4022ij9+te/bvpSAgC0AmIoAIBGdt/beOON04svvpi+9a1vpdGjR6dPfvKT6bLLLkvPP/986t27d0N2CQDQ6jVFDHXDDTekIUOGpG7dumXLHnvske67777K5yPZdcYZZ6SePXumLl26pJEjR6YFCxY047sCAMixpVT2wvbt05e//OWGvhwAoE1qbAwVia1IZG255ZapUCikX/ziF+nwww/PElvbbbddluz6/e9/n6ZOnZq6d++ezjzzzHTkkUemxx9/vEnfBwBASZJSN99882qfP+GEExpaHgCAVqspYqjDDjus2uPvf//7WeupJ598MktY3XTTTemWW25J+++/f/b85MmT0zbbbJM9v/vuuzfyHQAAlDgpdfbZZ1d7vGLFivThhx9m0xuvt956klIAADnEUDGTX7SIWrJkSdaN79lnn832OXz48MptBg8enAYOHJhmzpwpKQUAlH9S6r333ltlXQzSefrpp6dvfvObTVEuAIBWp6liqJdffjlLQsX4UTFu1B133JENnv7CCy9kCa4ePXpU275Pnz5p/vz5de5v2bJl2VK0ePHiepcFACD3MaVqinENYnyDGCPh1VdfbardAgC0ag2JobbeeussAbVo0aL029/+No0aNSrNmDGjwWWYMGFCGj9+fINfD61BxfiKNW5TGFdosn1BXp9HaHWz761u4M65c+c25S4BAFq9tY2hojXUFltskYYOHZollHbcccd03XXXpb59+6bly5enhQsXVts+Zt+L5+oyduzYLMFVXObMmdOo9wMA0Gwtpe6+++5qj2Pml3nz5qUf//jHaa+99qr3fh555JF05ZVXZuMfxOuj6fkRRxxR+fyJJ56YzShT1YgRI9L999/fkGIDAJRUU8VQNa1cuTLrfhdJqg4dOqRp06alkSNHZs/NmjUrzZ49O+vuV5dOnTplCwBAi09KVU0chYqKitSrV69slperrrqq3vuJQTmjZu+kk07KpiquzWc/+9ls1pgiARMAUK6aIoaKVk0HHXRQNnj5+++/n8209/DDD6cHHnggde/ePZ188slpzJgxacMNN0zdunVLZ511VpaQMsg5ANAqklJRG9cUIqCKZXUiCbW65uYAAOWiKWKod999N5ulL1pYRRJqyJAhWULqM5/5TPb8Nddck9q1a5e1lIrWU9HK/Prrr2+C0gMAtNCBzptL1Pz17t07bbDBBlkt4iWXXJJ69uxZ5/ZmjwEAWrObbrpptc937tw5TZw4MVsAAFpdUiqahNfX1VdfnRoquu5Ft75BgwalN998M33rW9/KWlbNnDkzrbPOOrW+xuwxAEBLlVcMBQDQapNSzz//fLasWLEim5I4vPbaa1miaOedd642TkJjHH300ZX/32GHHbLm6ZtvvnnWeuqAAw6oc5yFqgFftJQaMGBAo8oBANAU8oqhAABabVLqsMMOS127ds1mxotudeG9995LX/nKV9I+++yTzj333NQcNttss7TRRhulN954o86klNljAICWqlQxFABAS9SuIS+K2WGim1wxmArx/xjvaW1m31tb77zzTvrPf/6T+vXr12zHAABoLqWKoQAAWk1LqegS969//WuV9bEupiaurw8++CBr9VT09ttvpxdeeCGbwjiWGBsqZo6J2fdiTKnzzz8/bbHFFtksMgAA5aapYigAgDbbUurzn/981sz89ttvz1ovxfK73/0unXzyydnA5PX1zDPPpE9+8pPZEmIsqPj/d77znWxshZdeeil97nOfS1tttVW276FDh6ZHH31U9zwAoCw1VQwFANBmW0pNmjQpnXfeeenYY4/NBurMdtS+fRZQXXnllfXez7Bhw1KhUKjz+QceeKAhxQMAaJGaKoYCAGgNKgqrywqtwZIlS7JudSFmxVt//fVTS2wm371797Ro0aLUrVu3ZjlGS54gpz5XtyWXvxScMxqjvn9R6/sZKsXnsa38DrSV95m3hkcVDb8GTX3MPGKJlh5D5RE/QV4qxvtjTutUGNfMN0DIIZZoUPe9onnz5mXLlltumQVTjchvAQC0GWIoAIAGJqViBrwDDjggG+vp4IMPzoKqEE3PTWUMAFA7MRQAQCOTUqNHj04dOnRIs2fPTuutt17l+qOOOirdf//9DdklAECrJ4YCAGjkQOd//OMfs0HIN95442rrown6P/7xj4bsEgCg1RNDAQA0sqVUDM5ZtXav6L///W/q1KlTQ3YJANDqiaEAABqZlNpnn33SzTffXPm4oqIirVy5Ml1xxRVpv/32a8guocWImZ7WtEBefB5pjZ/Ztvy5FUMBADSy+14ETjFI5zPPPJOWL1+ezj///PSXv/wlq+V7/PHHG7JLAIBWTwwFANDIllLbb799eu2119Lee++dDj/88Kwp+pFHHpmef/75tPnmmzdklwAArZ4YCgCgES2lVqxYkT772c+mSZMmpf/5n/9Z25cDALRJYigAgEa2lIppjF966aW1fRkAQJsmhgIAaILue1/+8pfTTTfd1JCXAgC0WWIoAIBGDnT+0UcfpZ///OfpoYceSkOHDk3rr79+teevvvrqhuwWAKBVE0MBADQwKfXWW2+lTTfdNL3yyitp5513ztbFYJ1VxdTGAAD8HzEUAEAjk1JbbrllmjdvXpo+fXr2+Kijjko//OEPU58+fdZmNwAAbYoYCgCgkWNKFQqFao/vu+++bCpjAADqJoYCAGiigc7rCrAAAFgzMRQAwFompWKsg5rjHRj/AABg9cRQAACNHFMqavVOPPHE1KlTp+zx0qVL02mnnbbKzDG333772uwWAKBVE0MBADQyKTVq1Khqj7/85S+vzcsBWr3W0PChNbwHWr629jkTQwEANDIpNXny5LXZHAAAMRQAQNMPdA4AAAAADSEpBQAAAEDuJKUAAAAAyJ2kFAAAAAC5k5QCAAAAIHeSUgAAAADkTlIKAAAAgNxJSgEAAACQO0kpAAAAAHInKQUAAABA7iSlAAAAAMhd+/wPCQClV1FR6hIAAEDbJikFAAAAZaZifP1q2ArjCs1eFmgo3fcAAAAAyJ2kFAAAAAC5k5QCAAAAIHeSUgAAAADkTlIKAAAAgNxJSgEAAACQu/b5HxIAAAAoNxXjK+q1XWFcodnLQuugpRQAAAAAuZOUAgAAACB3klIAAAAA5E5SCgAAAIDcSUoBAAAAkDuz7wEAAEAbnjHPbHmUipZSAAAAAOROUgoAoIxMmDAh7brrrqlr166pd+/e6YgjjkizZs2qts3SpUvTGWeckXr27Jm6dOmSRo4cmRYsWFCyMgMA1EZSCgCgjMyYMSNLOD355JPpwQcfTCtWrEgHHnhgWrJkSeU2o0ePTvfcc0+aOnVqtv3cuXPTkUceWdJyAwDUZEwpAIAycv/991d7PGXKlKzF1LPPPpv23XfftGjRonTTTTelW265Je2///7ZNpMnT07bbLNNlsjafffdS1RyAIDqtJQCAChjkYQKG264YfYzklPRemr48OGV2wwePDgNHDgwzZw5s2TlBACoSUspAIAytXLlynTOOeekvfbaK22//fbZuvnz56eOHTumHj16VNu2T58+2XO1WbZsWbYULV68uJlLDgBQ4qTUI488kq688sqsRm/evHnpjjvuyAbrLCoUCmncuHHpxhtvTAsXLswCrhtuuCFtueWWpSw2AECLEGNLvfLKK+mxxx5r9ODp48ePb7JyQUuZ5h6Alq2k3fdiQM4dd9wxTZw4sdbnr7jiivTDH/4wTZo0KT311FNp/fXXTyNGjMhmlAEAaMvOPPPMdO+996bp06enjTfeuHJ937590/Lly7MKvapi9r14rjZjx47NugEWlzlz5jR7+QEAStpS6qCDDsqW2kQrqWuvvTZddNFF6fDDD8/W3XzzzVnT8zvvvDMdffTROZcWAKD0IkY666yzshbmDz/8cBo0aFC154cOHZo6dOiQpk2blkaOHJmtmzVrVpo9e3baY489at1np06dsgUAIE8tdkypt99+Oxv3oOognd27d0+77bZbNkhnXUkpYyIAAK29y17MrHfXXXelrl27Vo4TFXHSuuuum/08+eST05gxY7LBz7t165YlsSIhZeY9AKAlabGz7xUDrGgZVd9BOotjIkQwVlwGDBiQ2rKKijUvAED5iPE1o4vdsGHDUr9+/SqX3/zmN5XbXHPNNenQQw/NWkrtu+++Wbe922+/vaTlBgAom5ZSDRVjIkTNYNWWUm09MQUAtK7ue2vSuXPnbMzOusbtBABoCVpsS6niQJwxKGd9B+kMMR5CNFOvugAAAADQsrTYpFQM2hnJpxiks2qrp5iFr65BOgEAAAAoDyXtvvfBBx+kN954o9rg5i+88EI2KOfAgQPTOeecky655JK05ZZbZkmqb3/726l///7piCOOKGWxAQAAACjnpNQzzzyT9ttvv8rHxbGgRo0alaZMmZLOP//8tGTJknTqqaemhQsXpr333jvd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Y8akcePGpeeeey7tuOOOacSIEendd98tddEAAFosMRQA0NK1+KTU1VdfnU455ZT0la98JW277bZp0qRJab311ks///nPS100AIAWSwwFALR0LToptXz58vTss8+m4cOHV65r165d9njmzJklLRsAQEslhgIAykGLnn3v3//+d/r4449Tnz59qq2Px6+++mqtr1m2bFm2FC1atCj7uXjx4mYuLQBQCs19iy/HGGJtY6iSxU9L17xJvctQj30BAP+nOe/zxX0XCoXyTUo1xIQJE9L48eNXWT9gwICSlAcAaF7du5e6BOWvJcdP3S9zgQGgXO+x77//fuq+mmCtRSelNtpoo7TOOuukBQsWVFsfj/v27Vvra8aOHZsN6lm0cuXK9N///jf17NkzVVRUNEv2LwK2OXPmpG7dujX5/lkz16C0nP/Scw1KzzVo3degWMPXtWvXVC7WNobKO36qD79XjeccNp5z2HjOYeM5h43nHOZ/DiN+ioRU//79V7tdi05KdezYMQ0dOjRNmzYtHXHEEZVBUjw+88wza31Np06dsqWqHj16NHtZ46L4cJeWa1Bazn/puQal5xqUnmvQsBiqVPFTfbimjeccNp5z2HjOYeM5h43nHOZ7DlfXQqosklIhau1GjRqVdtlll/SpT30qXXvttWnJkiXZTDIAANRODAUAtHQtPil11FFHpX/961/pO9/5Tpo/f37aaaed0v3337/KwJ0AAPwfMRQA0NK1+KRUiGbmdXXXK7Vo6j5u3LhVmryTH9egtJz/0nMNSs81KD3XoPxiqDVxTRvPOWw857DxnMPGcw4bzzlsueeworCm+fkAAAAAoIm1a+odAgAAAMCaSEoBAAAAkDtJKQAAAAByJylVDxMnTkybbrpp6ty5c9ptt93S008/vdrtp06dmgYPHpxtv8MOO6Q//OEPuZW1tVqba3DjjTemffbZJ22wwQbZMnz48DVeM5r2d6Do1ltvTRUVFemII45o9jK2dmt7DRYuXJjOOOOM1K9fv2wwwq222srfopyvwbXXXpu23nrrtO6666YBAwak0aNHp6VLl+ZW3tbkkUceSYcddljq379/9jflzjvvXONrHn744bTzzjtnn/8tttgiTZkyJZey0jw+97nPpYEDB2a/f/F37fjjj09z584tdbHKxt///vd08sknp0GDBmV/kzbffPNssNrly5eXumhl5fvf/37ac88903rrrZd69OhR6uK06hiSht//qG7ChAlp1113TV27dk29e/fOvpfMmjWr1MUqKzfccEMaMmRI6tatW7bsscce6b777muy/UtKrcFvfvObNGbMmOzG/dxzz6Udd9wxjRgxIr377ru1bv/EE0+kY445JrvxP//889mHPpZXXnkl97K31WsQX0TiGkyfPj3NnDkz+zJ44IEHpn/+85+5l70tnv+qAfB5552XJQjJ9xrEl4zPfOYz2TX47W9/m914I1n7iU98Iveyt9VrcMstt6QLL7ww2/5vf/tbuummm7J9fOtb38q97K3BkiVLsnMeX27q4+23306HHHJI2m+//dILL7yQzjnnnPTVr341PfDAA81eVppHXMvbbrst+3v2u9/9Lr355pvpC1/4QqmLVTZeffXVtHLlyvSTn/wk/eUvf0nXXHNNmjRpkr9Jaynur1/84hfT6aefXuqitOoYkobf/1jVjBkzsoraJ598Mj344INpxYoV2XfDOLfUz8Ybb5wuu+yy9Oyzz6Znnnkm7b///unwww/P7idNImbfo26f+tSnCmeccUbl448//rjQv3//woQJE2rd/ktf+lLhkEMOqbZut912K3zta19r9rK2Vmt7DWr66KOPCl27di384he/aMZStl4NOf9xzvfcc8/Cz372s8KoUaMKhx9+eE6lbZ3W9hrccMMNhc0226ywfPnyHEvZuq3tNYht999//2rrxowZU9hrr72avaytXYQud9xxx2q3Of/88wvbbbddtXVHHXVUYcSIEc1cOvJy1113FSoqKvyda4QrrriiMGjQoFIXoyxNnjy50L1791IXo9XH8Kz9/Y81e/fdd7NzOWPGjFIXpaxtsMEG2Xe9pqCl1BpqQyIbGN2/itq1a5c9jhY4tYn1VbcPUSNQ1/Y0/TWo6cMPP8wy4htuuGEzlrR1auj5v/jii7PmsdFikPyvwd133501q41aoT59+qTtt98+XXrppenjjz/OseRt+xpE9454TbGbwltvvZV1nzz44INzK3db5l7cuv33v/9Nv/rVr7Lfsw4dOpS6OGVr0aJFYiNadAwPzfW3L/j71zDxfSKGaImWZvF9oylISq3Gv//97+ykx5e6quLx/Pnza31NrF+b7Wn6a1DTBRdckPXDrvkFheY5/4899ljWVSm6i1GaaxAJkOi2F6+LRMi3v/3tdNVVV6VLLrkkp1K3Lg25Bscee2yWnN17772zL80xfsuwYcN0lclJXffixYsXp//93/8tWblonLifr7/++qlnz55p9uzZ6a677ip1kcrWG2+8kX70ox+lr33ta6UuCq1UU8Tw0NSiG3N06d9rr72ySlvq7+WXX05dunTJxuo87bTT0h133JG23Xbb1BQkpWjVou9rZHLjlyYGWKR5vf/++9ngs5GQ2mijjUpdnDZ9w42Waj/96U/T0KFD01FHHZX+53/+Jxs/hHzE2HbROu3666/PxtG4/fbb0+9///v0ve99r9RFgxYjxl2LgXtXt8RYSEXf/OY3s/E6//jHP6Z11lknnXDCCTEMRWrL1vYchhhj87Of/Ww2NtIpp5yS2rqGnEOgPEUvghjrOb4fsnZi8p4Yp/Opp57KxtUbNWpU+utf/5qaQvsm2UsrFV+qI+hZsGBBtfXxuG/fvrW+JtavzfY0/TUo+sEPfpAlpR566KFstgCa//zHwLMxuHbMElI1QRLat2+fDVAbLUZo3t+BmJkqWufE64q22WabrGYymtN37Nix2cvd1q9BtE6LBG0Mrh1iJtZo5nzqqadmCcLowkDzqeteHDPGxMxjtAznnntuOvHEE1e7zWabbVbtdzGWmE00/qbFRCYxcG1TdR9oC+cwZiyMQeOj62NUXLD255Dmj+GhOZx55pnp3nvvzWY0jIG7WTvx/SFmMw5R6f3nP/85XXfdddkEGo0lKbWGEx8nfNq0aZVT2scX7HgcH+raRGAUz0ezwKIY5b8tB0x5X4NwxRVXZNP2xkxLu+yyS44lbtvnf/DgwVnTzqouuuiirAVV/NGKLxA0/+9ANEmO2d9iu2Ly47XXXsuSVRJS+VyDGMuuZuKpmCRs6y078hD33Oi6WpV7ccvTq1evbGmIYoXHsmXLUlu2NucwWkhFQir+nk2ePFlyvAk+hzR9DA9NLeKus846K+s5Ey3ZBw0aVOoitQorV65suntwkwyX3ordeuuthU6dOhWmTJlS+Otf/1o49dRTCz169CjMnz8/e/74448vXHjhhZXbP/7444X27dsXfvCDHxT+9re/FcaNG1fo0KFD4eWXXy7hu2hb1+Cyyy4rdOzYsfDb3/62MG/evMrl/fffL+G7aDvnvyaz7+V/DWbPnp3NOHnmmWcWZs2aVbj33nsLvXv3LlxyySUlfBdt6xrE3/64Br/+9a8Lb731VuGPf/xjYfPNN89maGXtxd/v559/PlsidLn66quz///jH//Ino9zH9egKM75euutV/jmN7+Z3YsnTpxYWGeddQr3339/Cd8FDfXkk08WfvSjH2XX/O9//3th2rRp2Qyv8Tu1dOnSUhevLLzzzjuFLbbYonDAAQdk/68aH1F/8TcnPofjx48vdOnSpfLvkhizYfdOGn//Y81OP/30bLbMhx9+uNrfvg8//LDURSsbF154YTZb4dtvv1146aWXsscxA27Et01BUqoeIhAaOHBgluiIqU0jOCr69Kc/nX3pruq2224rbLXVVtn2MSX173//+xKUuu1eg0022ST7o11ziS+J5PM7UJWkVGmuwRNPPFHYbbfdsmBws802K3z/+98vfPTRRyUoedu8BitWrCh897vfzb40d+7cuTBgwIDC17/+9cJ7771XotKXt+nTp9f6d714zuNnXIOar9lpp52y6xW/AzGFO+UpAuD99tuvsOGGG2Z/0zbddNPCaaedliVXqJ/4/Nf2O6R+eu3E35razmH8vWHt7500/v7HmtX1t09cUH8nnXRS9h07fo979eqVVXA0VUIqVMQ/TdPmCgAAAADqR2dyAAAAAHInKQUAAABA7iSlAAAAAMidpBQAAAAAuZOUAgAAACB3klIAAAAA5E5SCgAAAIDcSUoBAAAAkDtJKaDNGjZsWDrnnHNKXQwAgLIihgKaiqQUUJYOO+yw9NnPfrbW5x599NFUUVGRXnrppdzLBQDQkomhgJZEUgooSyeffHJ68MEH0zvvvLPKc5MnT0677LJLGjJkSEnKBgDQUomhgJZEUgooS4ceemjq1atXmjJlSrX1H3zwQZo6dWo64ogj0jHHHJM+8YlPpPXWWy/tsMMO6de//vVq9xk1g3feeWe1dT169Kh2jDlz5qQvfelL2foNN9wwHX744envf/97E787AIDmIYYCWhJJKaAstW/fPp1wwglZsFMoFCrXRzD18ccfpy9/+ctp6NCh6fe//3165ZVX0qmnnpqOP/749PTTTzf4mCtWrEgjRoxIXbt2zZq3P/7446lLly5ZE/jly5c30TsDAGg+YiigJZGUAsrWSSedlN588800Y8aMas3OR44cmTbZZJN03nnnpZ122iltttlm6ayzzsoCn9tuu63Bx/vNb36TVq5cmX72s59ltYbbbLNNdrzZs2enhx9+uIneFQBA8xJDAS2FpBRQtgYPHpz23HPP9POf/zx7/MYbb2S1bzFWQtT0fe9738sCn2giHrVxDzzwQBb8NNSLL76YHSNq+WJ/scS+ly5dmgV2AADlQAwFtBTtS10AgMaI4Clq8CZOnJjVuG2++ebp05/+dLr88svTddddl6699tosqFp//fWzqYtX10Q8xkOo2oy92Ny86lgL0Zz9V7/61SqvjbEZAADKhRgKaAkkpYCyFgNmnn322emWW25JN998czr99NOzwCjGKogBNGNchBBNxl977bW07bbb1rmvCIrmzZtX+fj1119PH374YeXjnXfeOWt+3rt379StW7dmfmcAAM1HDAW0BLrvAWUtmn8fddRRaezYsVkwdOKJJ2brt9xyy2y64yeeeCL97W9/S1/72tfSggULVruv/fffP/34xz9Ozz//fHrmmWfSaaedljp06FD5/HHHHZc22mijLFCLJu5vv/12Ng7CN77xjVqnVQYAaKnEUEBLICkFtIrm5++99142q0v//v2zdRdddFFWKxfrhg0blvr27ZtNcbw6V111VRowYEDaZ5990rHHHpsN8hlTIRfF/x955JE0cODAdOSRR2aDdMaxYzwEtX4AQLkRQwGlVlGo2fkXAAAAAJqZllIAAAAA5E5SCgAAAIDcSUoBAAAAkDtJKQAAAAByJykFAAAAQO4kpQAAAADInaQUAAAAALmTlAIAAAAgd5JSAAAAAOROUgoAAACA3ElKAQAAAJA7SSkAAAAAUt7+P8AcHUjZK6kxAAAAAElFTkSuQmCC"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 6
  },
  {
   "cell_type": "markdown",
   "id": "b75de2b880a12c80",
   "metadata": {},
   "source": [
    "## 张量属性"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "89419379e8887c30",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([2, 3])\n",
      "torch.float32\n",
      "cpu\n"
     ]
    }
   ],
   "source": [
    "x = torch.rand(2, 3)\n",
    "\n",
    "print(x.shape)  # 张量形状\n",
    "print(x.dtype)  # 数据类型\n",
    "print(x.device)  # 存储设备(CPU/GPU)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ab507076a41a96a5",
   "metadata": {},
   "source": [
    "## 张量运算"
   ]
  },
  {
   "cell_type": "code",
   "id": "7eb681aad22dbe3",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-15T04:29:27.425242Z",
     "start_time": "2025-06-15T04:29:27.416260Z"
    }
   },
   "source": [
    "x = torch.tensor([1, 2, 3])\n",
    "y = torch.tensor([4, 5, 6])\n",
    "\n",
    "# 基本运算\n",
    "print(x + y)  # 加法\n",
    "print(x * y)  # 乘法\n",
    "\n",
    "print(x @ y)  # 点积, 对应元素相乘后相加\n",
    "print(torch.dot(x, y))  # 点积"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([5, 7, 9])\n",
      "tensor([ 4, 10, 18])\n",
      "tensor(32)\n",
      "tensor(32)\n"
     ]
    }
   ],
   "execution_count": 21
  },
  {
   "cell_type": "code",
   "id": "d675188d65305006",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-06-15T04:22:04.433541Z",
     "start_time": "2025-06-15T04:22:04.416842Z"
    }
   },
   "source": [
    "# 矩阵乘法\n",
    "import torch\n",
    "\n",
    "A = torch.tensor([[1, 2],\n",
    "                  [3, 4]])\n",
    "\n",
    "B = torch.tensor([[5, 6],\n",
    "                  [7, 8]])\n",
    "\n",
    "# 矩阵乘法的三种写法\n",
    "print(A @ B)\n",
    "print(torch.mm(A, B))  # 只支持二维矩阵\n",
    "print(torch.matmul(A, B))  # 支持多维矩阵\n",
    "\n",
    "# 矩阵不能点积，矩阵只有点乘\n",
    "print(torch.dot(A, B))"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[19, 22],\n",
      "        [43, 50]])\n",
      "tensor([[19, 22],\n",
      "        [43, 50]])\n",
      "tensor([[19, 22],\n",
      "        [43, 50]])\n"
     ]
    },
    {
     "ename": "RuntimeError",
     "evalue": "1D tensors expected, but got 2D and 2D tensors",
     "output_type": "error",
     "traceback": [
      "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[0;31mRuntimeError\u001B[0m                              Traceback (most recent call last)",
      "Cell \u001B[0;32mIn[17], line 16\u001B[0m\n\u001B[1;32m     13\u001B[0m \u001B[38;5;28mprint\u001B[39m(torch\u001B[38;5;241m.\u001B[39mmatmul(A, B))  \u001B[38;5;66;03m# 支持多维矩阵\u001B[39;00m\n\u001B[1;32m     15\u001B[0m \u001B[38;5;66;03m# 矩阵不能点积，矩阵只有点乘\u001B[39;00m\n\u001B[0;32m---> 16\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[43mtorch\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mdot\u001B[49m\u001B[43m(\u001B[49m\u001B[43mA\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mB\u001B[49m\u001B[43m)\u001B[49m)\n",
      "\u001B[0;31mRuntimeError\u001B[0m: 1D tensors expected, but got 2D and 2D tensors"
     ]
    }
   ],
   "execution_count": 17
  },
  {
   "cell_type": "code",
   "id": "b7ea6575cd8be0fe",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-14T14:26:57.667413Z",
     "start_time": "2025-07-14T14:26:22.260972Z"
    }
   },
   "source": [
    "# 矩阵点乘，对应元素相乘\n",
    "import torch\n",
    "\n",
    "A = torch.tensor([[1, 2],\n",
    "                  [3, 4]])\n",
    "\n",
    "B = torch.tensor([[5, 6],\n",
    "                  [7, 8]])\n",
    "\n",
    "# 矩阵点乘的两种写法\n",
    "print(A * B)\n",
    "print(torch.mul(A, B))"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 5, 12],\n",
      "        [21, 32]])\n",
      "tensor([[ 5, 12],\n",
      "        [21, 32]])\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-14T14:28:20.167538Z",
     "start_time": "2025-07-14T14:28:20.144878Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 形状是(2, 2, 3)\n",
    "A = torch.tensor([\n",
    "    [[1, 2, 3], [4, 5, 6]],\n",
    "    [[7, 8, 9], [10, 11, 12]]\n",
    "])\n",
    "\n",
    "A"
   ],
   "id": "f1ff1cb1a3b898f6",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[[ 1,  2,  3],\n",
       "         [ 4,  5,  6]],\n",
       "\n",
       "        [[ 7,  8,  9],\n",
       "         [10, 11, 12]]])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 3
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-14T14:28:36.885876Z",
     "start_time": "2025-07-14T14:28:36.759204Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 转置 将第一维度和第二维度转置，从第零维度开始\n",
    "A.transpose(1, 2).shape"
   ],
   "id": "8df2a56315a8cd6b",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.Size([2, 3, 2])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 4
  },
  {
   "cell_type": "code",
   "id": "72de5420a46e8d82",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-14T14:34:32.800033Z",
     "start_time": "2025-07-14T14:34:32.462253Z"
    }
   },
   "source": [
    "# 矩阵批量乘法，一定要三维，第0维是batch_size\n",
    "import torch\n",
    "\n",
    "# 形状是(2, 2, 3)\n",
    "A = torch.tensor([\n",
    "    [[1, 2, 3], [4, 5, 6]],\n",
    "    [[1, 2, 3], [4, 5, 6]]\n",
    "])\n",
    "\n",
    "# 形状是(2, 2, 3)\n",
    "B = torch.tensor([\n",
    "    [[7, 8, 9], [10, 11, 12]],\n",
    "    [[8, 8, 9], [10, 11, 12]]\n",
    "])\n",
    "\n",
    "# 本质上就是矩阵乘法，所以需要改变维度, batch\n",
    "print(torch.bmm(A, B.transpose(1, 2)))\n",
    "\n",
    "print(torch.matmul(A, B.transpose(1, 2)))\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[[ 50,  68],\n",
      "         [122, 167]],\n",
      "\n",
      "        [[ 51,  68],\n",
      "         [126, 167]]])\n",
      "tensor([[[ 50,  68],\n",
      "         [122, 167]],\n",
      "\n",
      "        [[ 51,  68],\n",
      "         [126, 167]]])\n"
     ]
    }
   ],
   "execution_count": 5
  },
  {
   "cell_type": "markdown",
   "id": "bbc5a77d1e229567",
   "metadata": {},
   "source": [
    "## 自动微分 (Autograd)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "da1a6a2612c0cad5",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-05-13T12:44:23.833144Z",
     "start_time": "2025-05-13T12:44:23.819992Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor(7.)\n"
     ]
    }
   ],
   "source": [
    "# 创建需要梯度的张量\n",
    "x = torch.tensor(2.0, requires_grad=True)\n",
    "\n",
    "# 定义计算\n",
    "y = x ** 2 + 3 * x + 1\n",
    "\n",
    "# 计算梯度\n",
    "y.backward()\n",
    "\n",
    "# 查看梯度\n",
    "print(x.grad)  # dy/dx = 2x + 3 = 7 (当x=2时)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc62160857019080",
   "metadata": {},
   "source": [
    "## Dataset和DataLoader\n",
    "\n",
    "Dataset和DataLoader是PyTorch中用于处理数据集和数据加载的组件。\n",
    "\n",
    "Dataset类是一个抽象类，用于定义数据集的接口。DataLoader类是一个迭代器，用于加载数据集。"
   ]
  },
  {
   "cell_type": "code",
   "id": "b726597e2b87421",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-14T15:11:58.499948Z",
     "start_time": "2025-07-14T15:11:58.484318Z"
    }
   },
   "source": [
    "from torch.utils.data import Dataset, DataLoader\n",
    "\n",
    "\n",
    "# 自定义数据集类（继承Dataset）\n",
    "class ZhouyuDataset(Dataset):\n",
    "\n",
    "    def __init__(self, data):\n",
    "        self.data = data\n",
    "\n",
    "    def __len__(self):\n",
    "        \"\"\"返回数据集大小（必须实现）\"\"\"\n",
    "        return len(self.data)\n",
    "\n",
    "    def __getitem__(self, index):\n",
    "        \"\"\"访问单个样本（必须实现），index是索引位置\"\"\"\n",
    "        # return [i + 1 for i in self.data[index]]\n",
    "        return torch.tensor(self.data[index]) + 1"
   ],
   "outputs": [],
   "execution_count": 6
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-14T15:12:02.314557Z",
     "start_time": "2025-07-14T15:12:02.250190Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 创建数据集实例，比如我们的训练样本\n",
    "data = list(range(1, 11))\n",
    "print(data)\n",
    "\n",
    "dataset = ZhouyuDataset(data)\n",
    "\n",
    "# 查看前5个样本\n",
    "dataset[:5]"
   ],
   "id": "58842ad35c9eb461",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "tensor([2, 3, 4, 5, 6])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 7
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-14T15:15:25.483190Z",
     "start_time": "2025-07-14T15:15:25.467529Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 创建数据加载器DataLoader\n",
    "dataloader = DataLoader(\n",
    "    dataset,\n",
    "    batch_size=3,\n",
    "    shuffle=True  # 是否打乱数据\n",
    ")\n",
    "\n",
    "# 批量加载数据\n",
    "for batch in dataloader:\n",
    "    # 每个batch是形状为[batch_size]的张量\n",
    "    print(\"Batch:\", batch)"
   ],
   "id": "c2cda85e4ab830ab",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Batch: tensor([2, 6, 9])\n",
      "Batch: tensor([5, 3, 4])\n",
      "Batch: tensor([11,  8, 10])\n",
      "Batch: tensor([7])\n"
     ]
    }
   ],
   "execution_count": 9
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-14T15:17:59.575054Z",
     "start_time": "2025-07-14T15:17:59.563078Z"
    }
   },
   "cell_type": "code",
   "source": [
    "def custom_collate_fn(batch):\n",
    "    print(1)\n",
    "    return [item * 10 for item in batch]\n",
    "\n",
    "# 创建数据加载器DataLoader\n",
    "dataloader = DataLoader(\n",
    "    dataset,\n",
    "    batch_size=3,\n",
    "    collate_fn=custom_collate_fn,\n",
    "    shuffle=True  # 是否打乱数据\n",
    ")\n",
    "\n",
    "# 批量加载数据\n",
    "for batch in dataloader:\n",
    "    # 每个batch是形状为[batch_size]的张量\n",
    "    print(\"Batch:\", batch)"
   ],
   "id": "2dc025f0501cd788",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "Batch: [tensor(60), tensor(30), tensor(70)]\n",
      "1\n",
      "Batch: [tensor(100), tensor(20), tensor(90)]\n",
      "1\n",
      "Batch: [tensor(50), tensor(110), tensor(40)]\n",
      "1\n",
      "Batch: [tensor(80)]\n"
     ]
    }
   ],
   "execution_count": 11
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-14T15:21:48.479076Z",
     "start_time": "2025-07-14T15:21:48.446634Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from torch.utils.data import Dataset, DataLoader\n",
    "\n",
    "\n",
    "# 自定义数据集类（继承Dataset）\n",
    "class TupleDataset(Dataset):\n",
    "    def __init__(self, start, end):\n",
    "        \"\"\"初始化数据集：存储从start到end的整数\"\"\"\n",
    "        self.data = list(range(start, end))\n",
    "\n",
    "    def __len__(self):\n",
    "        \"\"\"返回数据集大小（必须实现）\"\"\"\n",
    "        return len(self.data)\n",
    "\n",
    "    def __getitem__(self, index):\n",
    "        \"\"\"访问单个样本（必须实现），index是索引位置\"\"\"\n",
    "        return f\"x{self.data[index]}\", f\"y{self.data[index]}\", f\"z{self.data[index]}\""
   ],
   "id": "d1c076dca413d09e",
   "outputs": [],
   "execution_count": 13
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-07-14T15:21:50.042193Z",
     "start_time": "2025-07-14T15:21:50.032163Z"
    }
   },
   "cell_type": "code",
   "source": [
    "dataset = TupleDataset(start=1, end=10)\n",
    "\n",
    "# 创建数据加载器DataLoader\n",
    "dataloader = DataLoader(\n",
    "    dataset,\n",
    "    batch_size=3,\n",
    "    # shuffle=True  # 是否打乱数据\n",
    ")\n",
    "\n",
    "# 批量加载数据\n",
    "for batch in dataloader:\n",
    "    # 每个batch是形状为[batch_size]的张量\n",
    "    print(\"Batch:\", batch)\n"
   ],
   "id": "ef94ca395eec0a3e",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Batch: [('x1', 'x2', 'x3'), ('y1', 'y2', 'y3'), ('z1', 'z2', 'z3')]\n",
      "Batch: [('x4', 'x5', 'x6'), ('y4', 'y5', 'y6'), ('z4', 'z5', 'z6')]\n",
      "Batch: [('x7', 'x8', 'x9'), ('y7', 'y8', 'y9'), ('z7', 'z8', 'z9')]\n"
     ]
    }
   ],
   "execution_count": 14
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.18"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
